#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
@Project: kubeext-SDS 
@File: snap.py
@Author: admin
@Date: 2022/6/9 10:59 
@desc: 
"""
import os

from testconstant import KUBESDS_TEST_FILE_STORAGE_TYPE, DEFAULT_VOL_TYPE, CEPH_DEV, KUBESDS_TEST_BLOCK_STORAGE_TYPE
from util import getArgparseParam, check_pool_info, get_random_uuid, get_cstor_pool
from utils.adm_exc.parsers import createExternalSnapshotParser, deleteExternalSnapshotParser, showDiskSnapshotParser, \
    revertExternalSnapshotParser
from utils.constant.constant import KUBESDS_TEST_ENV_VALUE, KUBESDS_TEST_ENV_KEY, KUBESDS_LOG, VIRTUAL_MACHINE_DISK, \
    VIRTUAL_MACHINE_DISK_SNAPSHOT
from utils.exception import KubdesdsExecuteException
from utils.logger import set_logger
from utils.utils import create_all_jsondict, get_snapshot_info_to_k8s, K8SInfoUtil, K8SUtil

logger = set_logger(os.path.basename(__file__), KUBESDS_LOG)


def snapTest(snap_uuid, disk_uuid, pool_name):
    """
    快照相关测试
    :param snap_uuid: 快照uuid
    :param disk_uuid: 所属云盘uuid
    :param pool_name: 云盘所属存储（此处对应的是数据库中的msid值（界面上可以直接查看），而非表cl_hostlocalstorage_inf对应的poolname）
    :return:
    """
    logger.debug('\n\n')
    logger.debug('***kubesds test snap [%s] start.' % snap_uuid)
    # 设置测试时，特有的环境变量内容
    os.environ[KUBESDS_TEST_ENV_KEY] = KUBESDS_TEST_ENV_VALUE
    try:
        pool_info = get_cstor_pool(pool_name)
        if not pool_info:
            raise KubdesdsExecuteException('kubesdsTestError', 'pool info is none.')
        # 1.创建云盘内部快照（默认云盘未挂载云主机）
        createExternalSnapshotTest(disk_uuid, pool_info, snap_uuid, pool_name)
        # 2.显示云盘内部快照
        showDiskSnapshotTest(disk_uuid, pool_info, snap_uuid)
        # 3.恢复云盘内部快照
        revertExternalSnapshotTest(disk_uuid, pool_info, snap_uuid)
        # 4.删除云盘内部快照
        deleteExternalSnapshotTest(disk_uuid, pool_info, snap_uuid)
    except Exception as e:
        raise KubdesdsExecuteException('kubesdsTestError', 'pool test error.')
    finally:
        # 去除测试时特有的环境变量内容
        if KUBESDS_TEST_ENV_KEY in os.environ:
            del os.environ[KUBESDS_TEST_ENV_KEY]


def createExternalSnapshotTest(disk_uuid, pool_info, snap_uuid, pool_name, vol_type=DEFAULT_VOL_TYPE):
    """
    创建云盘内部快照（针对数据盘创建的快照，不涉及内存快照或者云主机快照）
    :param disk_uuid: 云盘uuid
    :param vol_type: 默认为数据盘
    :param snap_uuid: 快照uuid
    :param pool_info: 通过cstor show-pool查询云盘所属存储所得信息
    :param pool_name: 云盘所属存储（此处对应的是数据库中的msid值（界面上可以直接查看），而非表cl_hostlocalstorage_inf对应的poolname）
    :return:
    """
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)
    vol_format = "qcow2" if pool_type in KUBESDS_TEST_FILE_STORAGE_TYPE else "raw"

    create_external_snapshot_params = {
        'vol': disk_uuid,
        'volumetype': vol_type,
        'name': snap_uuid,
        'format': vol_format,
        'domain': None,
        'memorysnapshot': None,
        'pool': pool,
        'type': pool_type,
    }

    createExternalSnapshotParser(getArgparseParam(create_external_snapshot_params))

    registerExternalSnapshotToK8sTest(disk_uuid, pool_info, snap_uuid, pool_name)
    
    logger.debug('***kubesds create test snapshot [%s] success.' % snap_uuid)


def registerExternalSnapshotToK8sTest(disk_uuid, pool_info, snap_uuid, pool_name):
    """
    注册创建测试快照至k8s中（通过上述创建的快照，并未注册至k8s中，此处重新注册）
    :param disk_uuid: 云盘uuid
    :param snap_uuid: 快照uuid
    :param pool_info: 通过cstor show-pool查询云盘所属存储所得信息
    :param pool_name: 云盘所属存储（此处对应的是数据库中的msid值（界面上可以直接查看），而非表cl_hostlocalstorage_inf对应的poolname）
    :return:
    """
    jsondicts = []
    snapshot_jsondict = None
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)
    # ceph-dev类型存储信息获取
    if pool_type in KUBESDS_TEST_BLOCK_STORAGE_TYPE:
        result = K8SInfoUtil(VIRTUAL_MACHINE_DISK, disk_uuid).get_info()
        uni = result['uni'] + '@%s' % snap_uuid
        result['uni'] = result['filename'] = result['current'] = uni
        snapshot_info = result
    # 文件系统类型存储信息获取
    else:
        snapshot_info = get_snapshot_info_to_k8s(pool_name, disk_uuid, snap_uuid)
    if pool_info:
        snapshot_jsondict = K8SUtil(VIRTUAL_MACHINE_DISK_SNAPSHOT, snap_uuid).get_create_str(snapshot_info)
    if snapshot_jsondict:
        jsondicts.append(snapshot_jsondict)
    if jsondicts:
        create_all_jsondict(jsondicts)


def showDiskSnapshotTest(disk_uuid, pool_info, snap_uuid, vol_type=DEFAULT_VOL_TYPE):
    """
    显示快照
    :param disk_uuid: 云盘uuid
    :param vol_type: 默认为数据盘
    :param snap_uuid: 快照uuid
    :param pool_info: 通过cstor show-pool查询云盘所属存储所得信息
    :return:
    """
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)

    show_external_snapshot_params = {
        'vol': disk_uuid,
        'volumetype': vol_type,
        'name': snap_uuid,
        'pool': pool,
        'type': pool_type,
    }

    showDiskSnapshotParser(getArgparseParam(show_external_snapshot_params))

    logger.debug('***kubesds show test snapshot [%s] success.' % snap_uuid)


def revertExternalSnapshotTest(disk_uuid, pool_info, snap_uuid, vol_type=DEFAULT_VOL_TYPE):
    """
    恢复云盘内部快照
    :param disk_uuid: 云盘uuid
    :param vol_type: 默认为数据盘
    :param snap_uuid: 快照uuid
    :param pool_info: 通过cstor show-pool查询云盘所属存储所得信息
    :return:
    """
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)
    vol_format = "qcow2" if pool_type in KUBESDS_TEST_FILE_STORAGE_TYPE else "raw"

    revert_external_snapshot_params = {
        'vol': disk_uuid,
        'volumetype': vol_type,
        'format': vol_format,
        'name': snap_uuid,
        'domain': None,
        'pool': pool,
        'type': pool_type,
    }

    revertExternalSnapshotParser(getArgparseParam(revert_external_snapshot_params))

    logger.debug('***kubesds revert test snapshot [%s] success.' % snap_uuid)


def deleteExternalSnapshotTest(disk_uuid, pool_info, snap_uuid, vol_type=DEFAULT_VOL_TYPE):
    """
    删除云盘内部快照
    :param disk_uuid: 云盘uuid
    :param vol_type: 默认为数据盘
    :param snap_uuid: 快照uuid
    :param pool_info: 通过cstor show-pool查询云盘所属存储所得信息
    :return:
    """
    # pool_type 存储所属类型: localfs|ipsan|nfs|glusterfs|ceph|ceph_dev
    # pool 存储类型和存储msid对应表cl_hostlocalstorage_inf的poolname内容
    pool_type, pool = check_pool_info(pool_info)

    delete_external_snapshot_params = {
        'vol': disk_uuid,
        'volumetype': vol_type,
        'name': snap_uuid,
        'domain': None,
        'pool': pool,
        'type': pool_type,
    }

    deleteExternalSnapshotParser(getArgparseParam(delete_external_snapshot_params))

    logger.debug('***kubesds delete test snapshot [%s] success.' % snap_uuid)


if __name__ == '__main__':
    # 以下pool值对应的是数据库中的msid值（界面上可以直接查看），而非表cl_hostlocalstorage_inf对应的poolname
    # ------------以下存储一存在于界面-----------------
    LocalFS_pool = '74d2724167034d8ab9244807f20bfbd8'
    NFS_pool = 'd1abfdee97a146f0aab87728f04e379e'
    CephBlock_pool = 'eb3e1a5398254ec8b67df674d00c4baa'
    SandStone_pool = '7cddd1df93d649a3852f31d89111822a'
    # ----------------------------------------------
    disk_id = '66fc78f3e78c42408d64ce688db2e294'
    snap_id = get_random_uuid()
    snapTest(snap_id, disk_id, SandStone_pool)
